package pl.dalkia.services.scanner;

import java.util.LinkedList;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import pl.dalkia.services.scanner.services.exceptions.LackOfDatePatternException;
import pl.dalkia.services.scanner.services.fetcher.Configuration;
import pl.dalkia.services.scanner.services.fetcher.Fetchable;
import pl.dalkia.services.scanner.services.matcher.Matchable;
import pl.dalkia.services.scanner.services.reader.Readable;
import pl.dalkia.services.scanner.services.writer.Writeable;

public class Scanner {

	private static final Logger log = LoggerFactory.getLogger(Scanner.class);
	
	private Fetchable fetcher;
	private Readable reader;
	private Writeable writer;

	public Scanner(Fetchable fetcher, Readable reader, Writeable writer) {
		super();
		this.fetcher = fetcher;
		this.reader = reader;
		this.writer = writer;
	}

	public void scan() {
		Configuration configuration = initializeConfiguration();
		List<String> resultLines = executeMatch(configuration);
		logByMode (resultLines, configuration);
		@SuppressWarnings("unused")
		boolean result = writer.write(resultLines);
	}

	private Configuration initializeConfiguration() {
		Configuration configuration = null;
		try {
			configuration = fetcher.fetch();
		} catch (LackOfDatePatternException e) {
			log.error("Lack of date pattern in configuration file");
			System.exit(1);
		}
		return configuration;
	}
	

	private void logByMode (List<String> resultLines, Configuration configuration){
		if(!resultLines.isEmpty() && !configuration.getSpecificPatterns().isEmpty()){
			log.info("Application has found deviation."); 
		}else if(!resultLines.isEmpty() && configuration.getSpecificPatterns().isEmpty()){
			log.info("Application has filtered ONLY by date");
		}else if(resultLines.isEmpty() && !configuration.getSpecificPatterns().isEmpty()){
			log.info("Everything is OK. Application found no deviations.");
		}else { 
			//(resultLines.isEmpty() && configuration.getSpecificPatterns().isEmpty()){
			log.info("Application has NOT filtered anything by date, because there was no matching patterns.");
		} 
	}
	
	private List<String> executeMatch(Configuration configuration) {
		String line = null;
		List<String> outputList = new LinkedList<String>();
		boolean isMatched;
		
		while ((line = reader.readLine()) != null) {
			isMatched = false;
			if (configuration.getDatePatternMatcher().match(line)) {

				List<Matchable> specificMatchers = configuration.getSpecificPatterns();
				
				if (!specificMatchers.isEmpty()) {
					for (Matchable specPattern : specificMatchers) {
						if (specPattern.match(line)) {
							isMatched = true;
							break;
						}
					}
					if(!isMatched){
						outputList.add(line);
					}
				} else{
					outputList.add(line);
				}
			}
		}
		return outputList;
	}
	
}
